import ms from 'ms';
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';

import { User } from '@src/user/entity/user.entity';
import { RedisService } from '@src/redis/redis.service';
import { ConfigurationService } from '@src/config/configuration.service';

import { AuthService } from '../auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(
    private readonly authService: AuthService,
    private readonly redisService: RedisService,
    private readonly configurationService: ConfigurationService,
  ) {
    super();
  }

  async validate(username: string, password: string): Promise<User | null> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException('账号或密码错误');
    }
    // 将权限信息缓存到 redis
    const jwtExpiresIn = this.configurationService.app.jwtExpiresIn;
    const redisTTL = ms(jwtExpiresIn as ms.StringValue);
    const permissions = user.roles.flatMap(
      (r) => r.permissions?.map((p) => p.code) ?? [],
    );
    await this.redisService.set(
      RedisService.key.userPerms(`${user.id}`),
      [...new Set(permissions)],
      redisTTL,
    );

    return user;
  }
}
